角色
store.dispatch
saga function
基於 redux 所以要建立一個 sagaMiddleware
會回傳一個 sagaMiddleware
在 sagaMiddleware 有一個 run 的參數
他是之前說過的 Generator Runner
在這個 Function 中 會利用 saga 產生 iterator
之前在生產者產生 task 之後需要有一個 channel 來暫存
這就是暫存的地方
預設會有一個 channel(之後有機會再說)
自己產生的話就可以用 actionChannel
import types from "../constants/actionTypes";
import { take, call, takeLatest, actionChannel } from 'redux-saga/effects';
import { loginSaga, logoutSaga } from './authSaga';
export function* watchLogin() {
yield takeLatest(types.LOGIN, loginSaga);
}
export function* watchLogout() {
yield takeLatest(types.LOGOUT, logoutSaga);
}
一般需要使用動併發的時候可以這樣處理
但是因為使用的是 takeLatest
所以當有重複的 Action 的時候
他會取消上一個 Action
但是如果我們希望可以一個一個處理
所有還沒處理到的 Action 先暫存一個地方
希望能有一個 queue 的機制
這時候可以利用 actionChannel
import types from "../constants/actionTypes";
import { take, call, takeLatest, actionChannel } from 'redux-saga/effects';
import { loginSaga, logoutSaga } from './authSaga';
export function* watchLogin() {
const requestChan = yield actionChannel(types.LOGIN);
while(true) {
const actionObject = yield take(requestChan);
yield call(loginSaga, actionObject);
}
}
export function* watchLogout() {
yield takeLatest(types.LOGOUT, logoutSaga);
}
上述的是利用 channel 暫存 task
由於使用 call 來做強制執行完之後
再由 while(true) 會重複執行下一個新的 task
import types from '~/constants/actionTypes';
import { connect } from 'react-redux';
import LoginScreen from './view';
const loginAction = payload => ({
type: types.LOGIN,
payload
});
const mapStateToProps = ({ auth }) => ({
auth
});
const mapDispatchToProps = dispatch => ({
handleLogin: payload => {
dispatch(loginAction(payload))
},
});
export default connect(mapStateToProps, mapDispatchToProps)(LoginScreen);
在 container 有描述 dispatch 產生新的 task
再由 saga 進行消費